import { _decorator, Component, error, Node } from 'cc';
import { ModuleBase } from './ModuleBase';
const { ccclass, property } = _decorator;
//负责管理所有模块，并且处理他们的生命周期函数。
export class ModuleMgr{
    //管理所有模块
    private _mapModule:Map<string,ModuleBase> = new Map();
    //单例。
    private static _instance:ModuleMgr = null;
    static get instance(){
        if(!this._instance){
            this._instance = new ModuleMgr();
        }
        return this._instance;
    }
    constructor(){

    }

    //添加接口。
    addModule(name:string,module:ModuleBase){
        if(name.length <=0||!module){
            return;
        }
        this._mapModule.set(name,module);
    }
    //获取接口。
    getModule<T>(name:string):T{
        if(name.length <=0){
            return null;
        }
        return this._mapModule.get(name) as T;
    }

    //移除
    deleteModule(name:string){
        //名字为空，或者不存在
        if(name.length <=0 || !this._mapModule.get(name)){
            return;
        }
        this._mapModule.delete(name);
    }

    //清空
    clearModule(){
        this._mapModule.clear();
    }

    destroyInstance(){
        ModuleMgr._instance = null;
    }


    //管理所有模块的生命周期。  

    onInitModule(...rest:any[]){
        for(let value of Array.from(this._mapModule.values())){
            //arguments所有参数形成的数组。
            //call()一个个写进去
            //apply()所有参数的数组。
            value.onInit.apply(value,arguments);
        }
    }
    onLateInitModule(...rest:any[]){
        for(let value of Array.from(this._mapModule.values())){
            value.onLateInit.apply(value,arguments);
        }
    }

    onUpdateModule(dt:number,...rest:any[]){
        for(let value of Array.from(this._mapModule.values())){                
            value.onUpdate.apply(value,arguments);
        }
    }

    onLateUpdateModule(dt:number,...rest:any[]){
        for(let value of Array.from(this._mapModule.values())){                
            value.onLateUpdate.apply(value,arguments);
        }
    }
    //处理模块与模块之间的交互。
    //消息名字 另一个模块要出发的函数名字。
    //哪一个模块  模块名字。
    //携带的数据。
    sendMsg(msgName:string,moduleName?:string,...rest:any[]){
        
        //通过模块名字取获取对应模块
        //模块名字没有，或者模块名字为空  设定，所有模块都可以接受到对应消息。 出发 msgName的值在这个模块里面对应的函数，执行。
        if(!moduleName || moduleName.length<=0){
            //遍历模块容器
            for(let value of Array.from(this._mapModule.values())){                
                //value 模块  中去获取msgName这个属性。 []
                let cb = value[msgName];
                if(cb){
                    //执行cb
                    cb.apply(value,rest);
                    continue;
                }
                //如果这个模块找不到 msgName对应的函数，那么调用默认响应
                value.handleMsg.apply(value,rest);
            }
            return;
        }

        //如果有传递名字，且不为空，那么就是单个模块响应。
        let module = this._mapModule.get(moduleName);
        if(!module){
            error('响应模块'+moduleName+'不存在');
            return;
        }
        let cb = module[msgName];
        if(cb){
            cb.apply(module,rest);
            return;
        }
        module.handleMsg.apply(module,rest);
    }
}




//玩家发射子弹。
//子弹层脚本.addBullet()
//ModuleMgr.instance.getModule<敌人层脚本呢>('名字')